import os, sys
from loggers import loggers

ACTIVE_PLUGINS_DIR = os.path.expanduser('~/.sms-middleware/plugins')
try:
    os.makedirs(ACTIVE_PLUGINS_DIR)
except:
    pass

INACTIVE_PLUGINS_DIR = os.path.join(ACTIVE_PLUGINS_DIR, 'inactive')
try:
    os.makedirs(INACTIVE_PLUGINS_DIR)
except:
    pass

sys.path.insert(0, ACTIVE_PLUGINS_DIR)
sys.path.insert(0, INACTIVE_PLUGINS_DIR)

def mock():
    pass

class PluginFactory(object):
    
    def __init__(self, logger):
        self.logger = logger
        self.active_plugins = {}
        self.inactive_plugins = {}

    def scan_for_plugins(self):
        self.active_plugins = {}
        self.inactive_plugins = {}
        self.logger.info("looking for plugins")
        self.logger.info("Active dir:%s" % ACTIVE_PLUGINS_DIR)
        self.logger.info("Inactive dir:%s" % INACTIVE_PLUGINS_DIR)

        # import module into a custom namespace
        for filename in os.listdir(ACTIVE_PLUGINS_DIR):
            filename, extension = os.path.splitext(filename)
            if extension == '.py':
                self.logger.info("processing file %s" % (filename))
                #try:
                space = __import__(filename, globals(), locals(), [])
                #except Exception, e:
                #    self.logger.error(e)
                #    self.logger.warning('skipping file %s' % filename)
                #    continue
                try:
                    reload(space)
                except:
                    print 'exception'
                    continue
                else:
                    space = __import__(filename, globals(), locals(), [])
                
                for key in dir(space):
                    method_fnd = getattr(space, key)
                    if key[:7] == 'plugin_' and type(method_fnd) == type(mock):
                        self.logger.info("acive method found: %s" % (key[7:]))
                        self.active_plugins[method_fnd] = {'filename':''.join((filename, extension)), 'name':key[7:],}
                        
        for filename in os.listdir(INACTIVE_PLUGINS_DIR):
            filename, extension = os.path.splitext(filename)
            if extension == '.py':
                self.logger.info("processing file %s" % (filename))
                #try:
                space = __import__(filename, globals(), locals(), [])
                #except Exception, e:
                #    self.logger.error(e)
                #    self.logger.warning('skipping file %s' % filename)
                #    continue
                try:
                    reload(space)
                except:
                    print 'exception'
                    continue
                else:
                    space = __import__(filename, globals(), locals(), [])
                
                for key in dir(space):
                    method_fnd = getattr(space, key)
                    if key[:7] == 'plugin_' and type(method_fnd) == type(mock):
                        self.logger.info("inactive method found: %s" % (key[7:]))
                        self.inactive_plugins[method_fnd] = {'filename':''.join((filename, extension)), 'name':key[7:],}
         
        self.logger.info("%d active plugin methods found" % (len(self.active_plugins)))
        self.logger.info("%d inactive plugin methods found" % (len(self.inactive_plugins)))
        
    def proceed(self, **kwargs):
        self.logger.info('executing sms-middleware plugins')
        for method in self.active_plugins.keys():
            self.logger.debug(type(method))
            #print kwargs
            try:
                method(**kwargs)
            except Exception, e:
                self.logger.exception(e)
            
    def activate(self, method):
        if method in self.active_plugins.keys():
            self.logger.warning('method %s already active' % (self.active_plugins[method]['name']))
        elif method in self.inactive_plugins.keys():
            filename = self.inactive_plugins[method]['filename']
            try:
                os.rename(os.path.join(INACTIVE_PLUGINS_DIR, filename),
                          os.path.join(ACTIVE_PLUGINS_DIR, filename))
            except OSError:
                pass
            for x in self.inactive_plugins.keys():
                if self.inactive_plugins[x]['filename'] == filename:
                    self.active_plugins[x] = self.inactive_plugins[x]
                    del self.inactive_plugins[x]
                    self.logger.info('method %s activated' % (self.active_plugins[x]['name']))
        else:
            self.logger.warning('no such method %s registered' % (method))
        
    def deactivate(self, method):
        if method in self.inactive_plugins.keys():
            self.logger.warning('method %s already inactive' % (self.inactive_plugins[method]['name']))
        elif method in self.active_plugins.keys():
            #print INACTIVE_PLUGINS_DIR, self.active_plugins[method]['filename']
            filename = self.active_plugins[method]['filename']
            try:
                os.rename(os.path.join(ACTIVE_PLUGINS_DIR, filename),
                          os.path.join(INACTIVE_PLUGINS_DIR, filename))
            except OSError:
                pass
            for x in self.active_plugins.keys():
                if self.active_plugins[x]['filename'] == filename:
                    self.inactive_plugins[x] = self.active_plugins[x]
                    del self.active_plugins[x]
                    self.logger.info('method %s deactivated' % (self.inactive_plugins[x]['name']))
        else:
            self.logger.warning('no such method %s registered' % (method))
            
    def install(self, full_filename):
        path, filename = os.path.split(full_filename)
        dst_filename = os.path.join(ACTIVE_PLUGINS_DIR, filename)
        self.logger.info('installing plugin from %s to %s' % (full_filename, dst_filename))
        #print path, filename
        import shutil
        shutil.copy(full_filename, dst_filename)
        #self.scan_for_plugins()
        return filename

        
if __name__ == '__main__':
    logger = loggers('plugin-factory', 'plugin-factory.log', 'INFO', True)
    
    p_factory = PluginFactory(logger)
    p_factory.scan_for_plugins()
    #p_factory.proceed(index='1', status='unread', sim_number='86876876', text='ala ma kota', interfaces=None)
    
    #for method in p_factory.active_plugins.keys():
    #    p_factory.deactivate(method)
    
    
    for method in p_factory.inactive_plugins.keys():
        p_factory.activate(method)
    

    #for method in p_factory.active_plugins.keys():
    #    p_factory.deactivate(method)
    
